use serde::{Deserialize, Serialize};

use crate::error::*;

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)]
#[serde(default)]
pub struct ListenerConf {
    // Listener address
    // Default "".
    pub address: String,

    // TODO: Current only support tcp type
    // Default "tcp".
    pub listener_type: String,

    // TODO: Current only support http app.
    // Default "http".
    pub app_name: String,

    // Only setting backlog to tcp listener.
    // Default 0.
    pub backlog: usize,

    // Only setting nodelay to tcp listener.
    // Default true.
    pub nodelay: bool,

    // Only setting reuseport to tcp listener.
    // Default: false.
    pub reuseport: bool,

    // Only setting reuseaddr to tcp listener.
    // Default: true.
    pub reuseaddr: bool,

    // Only setting ipv6only to ipv6 listener.
    // Default: true.
    pub ipv6only: bool,

    // Default: false.
    #[allow(dead_code)]
    pub tls_enable: bool,

    // Default: false.
    #[allow(dead_code)]
    pub h2_enable: bool,
}

impl Default for ListenerConf {
    fn default() -> Self {
        ListenerConf {
            address: "".to_string(),
            listener_type: "tcp".to_string(),
            app_name: "http".to_string(),
            backlog: 0,
            nodelay: true,
            reuseport: false,
            reuseaddr: true,
            ipv6only: true,
            tls_enable: false,
            h2_enable: false,
        }
    }
}

#[allow(dead_code)]
impl ListenerConf {
    pub fn validate(&mut self) -> Result<()> {
        if self.address.is_empty() {
            return Err(Error::from_msg(
                ErrorType::InvalidError,
                "invalid listener address",
            ));
        }

        if self.listener_type.is_empty() {
            return Err(Error::from_msg(
                ErrorType::InvalidError,
                "invalid listener type",
            ));
        }

        if self.app_name.is_empty() {
            return Err(Error::from_msg(
                ErrorType::InvalidError,
                "invalid listener app_name",
            ));
        }

        Ok(())
    }
}
